package com.dataView.task.earthquake;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.dataView.constants.Constants;
import com.dataView.model.earthquake.EarthquakeModel;
import com.dataView.util.DateUtil;
import com.dataView.util.FileUtile;
import com.dataView.util.JsoupHttpUtil;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.select.Elements;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.io.File;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author kanuo ;
 * 获取地震数据
 * @create 2020-07-23 10:44
 */
@Component
public class PullEarthquakeDataTask {

    protected Logger logger = LogManager.getLogger(getClass());

    @Scheduled(cron="0 0 * * * ?")
    public void getDatTask(){
        try {
            //整理老数据
            String path = new File("").getCanonicalPath() + File.separator + Constants.EARTHQUAKE_CONSTANTS.EARTHQUAKE_FILE_PATH;
            List<String> oldData = FileUtile.checkFileExistenceStatue(path).stream().filter(StringUtils::isNotBlank).collect(Collectors.toList());
            String startTime = Constants.EARTHQUAKE_CONSTANTS.START_TIME;
            String endTime = DateUtil.format(DateUtil.getTomorrowDay());

            if(!CollectionUtils.isEmpty(oldData)){
                JSONObject parse = JSONObject.parseObject(oldData.get(oldData.size() - 1));
                startTime = DateUtil.format(parse.getDate("O_TIME"));
            }
            //拉取新数据
            List<String> newData = checkPullDataStatus(startTime, endTime);
            //洗数据，并返回合并数据
            List<String> dataCount = washEarthquakeData(oldData, newData);
            //实例化
            FileUtile.deleteFileAndCreatNewFile(path,dataCount);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取新数据
     * @param startTime
     * @param endTime
     * @return
     */
    private List<String> checkPullDataStatus(String startTime,String endTime) {
        List<String> newData = new ArrayList<>();
        int pageMax = Integer.MAX_VALUE;
        for (int i = 1; i < pageMax; i++){
            String url = Constants.EARTHQUAKE_CONSTANTS.EARTHQUAKE_DATA_WEB_URL + String.format(Constants.EARTHQUAKE_CONSTANTS.URL_PARAM, i, startTime, endTime);
            logger.info("获取地震数据-传参：{}",url);
            String data = JsoupHttpUtil.getJsoupDocGetText(url);
            logger.info("获取地震数据-返回值：{}",data);
            if(StringUtils.isNotBlank(data)){
                //去掉数据体中的第一个括号与最后一个括号
                JSONObject parse = JSONObject.parseObject(data.substring(1, data.length() - 1));
                List<String> list = JSONObject.parseArray(parse.getString("shuju"), String.class);
                if(CollectionUtils.isEmpty(list)){
                    break;
                }
                //解析页码
                if(pageMax == Integer.MAX_VALUE){
//                    Document doc = Jsoup.parse(parse.getString("page"));
//                    String pageNum = doc.select("li[class=page]").select("a[title=尾页]").first().attr("page");
//                    pageMax = StringUtils.isNotBlank(pageNum)?Integer.valueOf(pageNum):Constants.PAGE_MAX_VALUE;
                    pageMax = Objects.nonNull(parse.getInteger("num"))?parse.getInteger("num"):Constants.PAGE_MAX_VALUE;
                    logger.info("获取地震数据-解析最大页码：{}",pageMax);
                }
                newData.addAll(list);
            } else {
                break;
            }
        }
        logger.info("获取地震数据-共获取新数据{}条",newData.size());
        return newData;
    }

    /**
     * 数据清洗：返回全量数据
     * @param oldData
     * @param newData
     * @return
     */
    private List<String>  washEarthquakeData(List<String> oldData,List<String> newData){
        List<String> dataCount = new ArrayList<>();
        newData.addAll(oldData);
        if(!CollectionUtils.isEmpty(newData) && newData.size() > oldData.size()){
            //类型转换+去重
            List<EarthquakeModel> dataList = new ArrayList<EarthquakeModel>(){{
                newData.forEach(str->this.add(JSONObject.parseObject(str,EarthquakeModel.class)));
            }}.stream().collect(
                    Collectors.collectingAndThen(
                            Collectors.toCollection(
                                    () -> new TreeSet<>(Comparator.comparing(po -> po.getId()))
                            ), ArrayList::new));
            dataCount = new ArrayList<String>(){{
                dataList.forEach(po-> this.add(JSON.toJSONString(po)));

            }};
        }
        logger.info("获取地震数据-数据合并完成，共{}条",dataCount.size());
        return dataCount;
    }

}
